//
//  SceneCollectionView.swift
//  home
//
//  Created by Yun Zeng on 2019/1/28.
//  Copyright © 2019 Yun Zeng. All rights reserved.
//

import UIKit
import AudioToolbox

class ScenesCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDelegate {
    
    static let identify = "home.controller.scene"
    var sceneManager: HomeSceneManager!
    var controller: UIViewController?
    var scenes: UICollectionView!
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let scene = sceneManager.scenes[indexPath.row]
        _ = self.sceneManager.execute(scene: scene)
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.sceneManager.scenes.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SceneCell.identifier, for: indexPath) as! SceneCell
        _ = cell.setScene(scene: self.sceneManager.scenes[indexPath.row]) { (scene) in
            self.forceTouchAt(index: indexPath.row, cell: cell)
        }
        return cell
    }
    
    func forceTouchAt(index: Int, cell: SceneCell) {
        Logger.Info("forceTouchAt:\(index)")
        let controller = SceneDetailController(scene: self.sceneManager.scenes[index])
        controller.modalPresentationStyle = .formSheet
        controller.isModalInPresentation = false
        controller.onBack = {
            cell.setStatic()
        }
        cell.isPlayed = true
        AudioServicesPlaySystemSound(1520)
        self.controller?.present(controller, animated: true)
    }
    
    @objc func handleLongPress(gestureRecognizer: UILongPressGestureRecognizer) {
        let pos = gestureRecognizer.location(in: self.scenes)
        guard let index = scenes.indexPathForItem(at: pos) else {
            return
        }
        guard let cell = scenes.cellForItem(at: index) as? SceneCell else {
            return
        }
        if cell.isPlayed == true {
            return
        }
        self.forceTouchAt(index: index.row, cell: cell)
    }
    
    func setSceneManager(manager: HomeSceneManager) {
        self.sceneManager = manager
        if manager.scenes.count == 0 {
            self.frame = CGRect(x: 0, y: self.frame.minY, width: self.frame.width, height: 0)
        } else {
            self.frame = CGRect(x: 0, y: self.frame.minY, width: self.frame.width, height: 160)
        }
        self.scenesView.reloadData()
        self.sceneManager.home?.serviceManager.addObserver(identify: ScenesCollectionView.identify, observer: self)
        Logger.Info("update scene manager: \(self.sceneManager.scenes)")
    }
    
    convenience init(manager: HomeSceneManager) {
        self.init(frame: CGRect())
        self.setSceneManager(manager: manager)
        self.cellCount = manager.scenes.count
    }
    
    fileprivate var scenesView: UICollectionView!
    private override init(frame: CGRect) {
        super.init(frame: frame)
        
        let layout = FlowLayout()
        layout.sectionInset = UIEdgeInsets(top: 4, left: 19, bottom: 0, right: 19)
        layout.itemSize = CGSize(width: 164, height: 60)
        layout.headerReferenceSize = CGSize(width: frame.width, height: 32)
        layout.minimumInteritemSpacing = 8.0
    
        layout.minimumLineSpacing = 8.0
        layout.estimatedItemSize = CGSize(width: 0, height: 0)
        
        scenes = UICollectionView(frame: .zero, collectionViewLayout: layout)
        scenes.isScrollEnabled = false
        scenes.dataSource = self
        scenes.delegate = self
        
        let gesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
        gesture.minimumPressDuration = 0.5
        scenes.addGestureRecognizer(gesture)
        
        scenes.register(SceneCell.self, forCellWithReuseIdentifier: SceneCell.identifier)
        scenes.register(UICollectionReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: ScenesCollectionView.identifier)
        
        scenes.backgroundColor = UIColor.clear
        scenes.delaysContentTouches = false
        self.addSubview(scenes)
        
        scenes.automaticallyAdjustsScrollIndicatorInsets = true
        scenes.translatesAutoresizingMaskIntoConstraints = false
        scenes.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        scenes.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        scenes.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
        scenes.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
        self.scenesView = scenes
    }
    
    var contentHeight: Int?
    private var cellCount: Int = 0
    
    override func layoutSubviews() {
        super.layoutSubviews()
        // 计算单元格占用高度
        let width = self.subviews.first!.frame.width
        var count = (width - 19.0) / (164.0 + 8.0)
        let last = (width - 19.0).truncatingRemainder(dividingBy: (164.0 + 8.0))
        if last < (19.0 - 8.0) {
            count = count - 1
        }
        self.contentHeight = (60 + 8) * (cellCount / Int(count)) + 32 + 4 + 4
        if CGFloat(cellCount).truncatingRemainder(dividingBy: CGFloat(Int(count))) >= 1.0 {
            self.contentHeight = self.contentHeight! + (60 + 8)
        }
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // 表头
    static let identifier = "ScenesCollectionViewHeader"
    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        var reusableView: UICollectionReusableView!
        if kind == UICollectionView.elementKindSectionHeader {
            reusableView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: ScenesCollectionView.identifier, for: indexPath)
            let label = UILabel(frame: CGRect(x: 22, y: 0, width: reusableView.frame.width - 20, height: reusableView.frame.height))
            let attributes: [NSAttributedString.Key : Any] = [
                NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16, weight: UIFont.Weight.regular),
                NSAttributedString.Key.kern: -0.36,
                NSAttributedString.Key.foregroundColor: UIColor.white]
            label.attributedText = NSAttributedString(string: "家居场景", attributes: attributes)
            label.textAlignment = NSTextAlignment.left
            reusableView.addSubview(label)
            // 文字阴影，让字体显得更白
            reusableView.layer.shadowColor = UIColor(red: 103/255, green: 103/255, blue: 103/255, alpha: 0.32).cgColor
            reusableView.layer.shadowOffset = CGSize.zero
            reusableView.layer.shadowRadius = 3.0
            reusableView.layer.shadowOpacity = 0.0
        }
        return reusableView
    }
}

extension ScenesCollectionView: ServiceUpdateObserver {
    func update(services: Set<Service>) {
        self.sceneManager.stateRefresh()
        self.scenesView.reloadData()
    }
}

extension ScenesCollectionView {
    public func setStatic() {
        for cell in self.scenesView.visibleCells {
            if let scene = cell as? SceneCell {
                scene.setStatic()
            }
        }
    }
}

// 场景每个单元格自动向左对齐
class FlowLayout: UICollectionViewFlowLayout {
    required init(minimumInteritemSpacing: CGFloat = 0, minimumLineSpacing: CGFloat = 0, sectionInset: UIEdgeInsets = .zero) {
        super.init()
        estimatedItemSize = UICollectionViewFlowLayout.automaticSize
        self.minimumInteritemSpacing = minimumInteritemSpacing
        self.minimumLineSpacing = minimumLineSpacing
        self.sectionInset = sectionInset
        sectionInsetReference = .fromSafeArea
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let layoutAttributes = super.layoutAttributesForElements(in: rect)!.map { $0.copy() as! UICollectionViewLayoutAttributes }
        guard scrollDirection == .vertical else { return layoutAttributes }
        let cellAttributes = layoutAttributes.filter({ $0.representedElementCategory == .cell })
        for (_, attributes) in Dictionary(grouping: cellAttributes, by: { ($0.center.y / 10).rounded(.up) * 10 }) {
            var leftInset = sectionInset.left
            for attribute in attributes {
                attribute.frame.origin.x = leftInset
                leftInset = attribute.frame.maxX + minimumInteritemSpacing
            }
        }
        
        return layoutAttributes
    }
}
